import json
import urllib2, urllib
import cookielib
import datetime
from flask import request
from frontend import app

base_url = 'http://localhost:8080/eventplanner/rest/'

def __init__(self):
    app.logger.info('REST wrapper init')

#### BASIC REST COMMUNICATION ####

def post(url, params=None):
    """ HTTP POST <params> to REST API. Returns response. """

    # Send cookies with every request
    ch = CookieHandling()
    opener = urllib2.build_opener()
    if ch.get_client_cookies():
        cookies_string = ''
        for cookie in ch.get_client_cookies():
            cookies_string += '%s=%s; ' % (cookie, ch.get_client_cookies()[cookie])
        opener.addheaders.append(('Cookie', cookies_string))
    urllib2.install_opener(opener)

    try:
        if params:
            params = urllib.urlencode(params)
            postreq =  urllib2.urlopen(base_url + url, params)
        else:
            postreq =  urllib2.urlopen(base_url + url, '')

        return postreq.read()

    except:
        return None

def get(url, params=None):
    """ HTTP GET <params> to REST API. Returns response. """

    # Send cookies with every request
    ch = CookieHandling()
    opener = urllib2.build_opener()
    if ch.get_client_cookies():
        cookies_string = ''
        for cookie in ch.get_client_cookies():
            cookies_string += '%s=%s; ' % (cookie, ch.get_client_cookies()[cookie])
        opener.addheaders.append(('Cookie', cookies_string))
    urllib2.install_opener(opener)

    try:
        if params:
            params = urllib.urlencode(params)
            getreq = urllib2.urlopen(base_url + url, '?%s' % params)
        else:
            getreq = urllib2.urlopen(base_url + url)

        return getreq.read()

    except:
        return None

#### SESSION MANAGEMENT ####

def signin(username, password):
    """ Sign in to the REST API. Returns True when succeeded. """

    try:
        if post('user/signin', {'username' : username, 'password' : password }).lower() == 'true':
            return True
        else:
            return False

    except:
        return False

def logged_in():
    """ Checks if currently logged in. Returns True or False. """

    try:
        if get('user/isloggedin').lower() == 'true':
            return True
        else:
            return False

    except:
        return False

def get_authlevel():
    """ Returns authlevel if logged in """

    if logged_in():
        try:
            return json.loads(get('user/authlevel'))
        except:
            return None

def get_username():
    """ Returns username  """

    if logged_in():
        try:
            return get('user/info')
        except:
            return ''

def signout():
    """ Sign out. No response."""

    try:
        post('user/signout')
    except:
        pass

#### CALENDAR / EVENT GETTERS ####

def get_todays_events():
    try:
        return json.loads(get('event/todays'))
    except:
        return {}


def get_calendars():
    """ Get all visible calendars """

    try:
        return json.loads(get('calendar'))
    except:
        return {}

def get_calendar(calid):
    """ Get calendar by ID """

    try:
        return json.loads(get('calendar/%s' % calid))
    except:
        return {}

def get_event(calid, evid):
    """ Get event by calendar and event IDs  """

    try:
        event = json.loads(get('calendar/%s/event/%s' % (calid, evid)))
        # Convert date
        event['start'] = datetime.datetime.fromtimestamp(int(int(event['start'])/1000)).strftime('%d-%m-%Y %H:%M')
        event['end'] = datetime.datetime.fromtimestamp(int(int(event['end'])/1000)).strftime('%d-%m-%Y %H:%M')

        return event

    except:
        return {}

#### TOKEN FUNCTIONALITY ####

def gen_token():
    """ Generate new token, return token-string """

    try:
        return json.loads(post('token/new'))
    except:
        return ''

def get_ical(token):
    """ Get ical-data by token-string """

    try:
        return get('token/ical/%s' % token)
    except:
        return ''

def get_tokens():
    """ Return tokens if logged in """

    try:
        if logged_in():
            tokens = []
            token_strings =  json.loads(get('token/tokens'))
            for token in token_strings:

                token_id = token_get_id(token)
                token_name = token_get_name(token)
                tokens.append({'id' : token_id, 'token' : token, 'name' : token_name})

            return tokens
    except:
        return []

def token_get_id(token):
    """ Return token's ID by token string """

    tokendata = json.loads(get('token/%s' % token))
    return tokendata[0][0]

def token_get_name(token):
    """ Return token's name by token string """

    tokendata = json.loads(get('token/%s' % token))
    return tokendata[0][1]

def token_get_feeds(token_id):
    """ Get token's feeds by token id """

    feeds = json.loads(get('token/%s/feeds' % token_id))
    for feed in feeds:
        if feed == None:
            return []
    return feeds

def token_get_tags(token_id):
    """ Get token's tags by token id """

    tags = json.loads(get('token/%s/tags' % token_id))
    for tag in tags:
        if tag == None:
            return []
    return tags

def token_add_feed(token_id, feed_id):
    """ Add feed to token """

    return post('token/%s/feed/add/%s' % (token_id, feed_id))

def token_del_feed(token_id, feed_id):
    """ Delete feed from token """

    return post('token/%s/feed/del/%s' % (token_id, feed_id))

def token_add_tag(token_id, tag):
    """ Add tag to token """

    return post('token/%s/tag/add/%s' % (token_id, tag))

def token_del_tag(token_id, tag):
    """ Delete tag from token """

    return post('token/%s/tag/del/%s' % (token_id, tag))

def token_get_groups(token_id):
    """ Get token's groups by token-id """

    groups = json.loads(get('token/%s/targets' % token_id))
    for group in groups:
        if group == None:
            return []
    return groups

def token_add_group(token_id, doelgroep):
    """ Add group to token """

    doelgroep = urllib.quote(doelgroep)
    return post('token/%s/target/add/%s' % (token_id, doelgroep))

def token_del_group(token_id, doelgroep):
    """ Delete group from token """

    doelgroep = urllib.quote(doelgroep)
    return post('token/%s/target/del/%s' % (token_id, doelgroep))

def get_doelgroepen():
    """ Get all groups """
    return json.loads(get('groups'))

def token_get_orgs(token_id):
    """ Get token's organizers by token-id """

    groups = json.loads(get('token/%s/organizers' % token_id))
    for group in groups:
        if group == None:
            return []
    return groups

def token_add_org(token_id, doelgroep):
    """ Add org to token """

    doelgroep = urllib.quote(doelgroep)
    return post('token/%s/organizer/add/%s' % (token_id, doelgroep))

def token_del_org(token_id, doelgroep):
    """ Delete group from token """

    doelgroep = urllib.quote(doelgroep)
    return post('token/%s/organizer/del/%s' % (token_id, doelgroep))



class CookieHandling:

    def __init__(self):
        #print 'CookieHandling INIT'
        pass

    def get_client_cookies(self):
        """ Returns client's cookies for our domain in dict format. """
        return request.cookies

    def get_backend_cookies(self):
        """ Returns backend's cookies in cookiejar format (iterable as Cookie-objects) """

        url = base_url + 'user/info/' # URL does not matter
        cookiejar = cookielib.LWPCookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
        urllib2.install_opener(opener)

        # Send browser's cookies
        if self.get_client_cookies():
            cookies_string = ''
            for cookie in self.get_client_cookies():
                cookies_string += '%s=%s; ' % (cookie, self.get_client_cookies()[cookie])
            opener.addheaders.append(('Cookie', cookies_string))
        req = urllib2.Request(url)
        urllib2.urlopen(req)

        return cookiejar